package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.exception.LogicException;
import cn.wolfcode.luowowo.repository.UserInfoRepository;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.AssertUtils;
import cn.wolfcode.luowowo.util.Consts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserInfoRepository repository;


    @Autowired
    private IUserInfoRedisService userInfoRedisService;



    public UserInfo get(String id) {
        Optional<UserInfo> op = repository.findById(id);
        if (op.isPresent()){
            return op.get();
        }
        return null;
    }


    /**
     * 根据Phone查询用户是否存在
     * 返回true或者false
     * 存在返回false
     * 不存在返回true
     * @param phone
     * @return
     */
    public boolean checkPhone(String phone) {
        UserInfo userInfo = repository.findByPhone(phone);
        return  userInfo == null;
    }

    /**
     * 发送和往redis中存入验证码
     * @param phone
     *
     */
    public void sendVerifyCode(String phone) {

        // 生成验证码
        String code = UUID.randomUUID()
                .toString()
                .replaceAll("-", "") // 把全部-换成""
                .substring(0, 4);// 截取前四个索引;

        // 模拟发送短信:(Consts这是个工具类.如果以后要改动时间.在工具里里面改动即可)
        String say = "【叩丁狼】: 您好,您的注册验证码是:"
                     + code
                     + "请在"
                     + Consts.VERIFY_CODE_VAI_TIME
                     + "分钟内输入,"
                     + "过时将失效";
        System.err.println(say);

        // 往redis中存入验证码
        userInfoRedisService.setVerifyCode(phone,code);

        // 真实发送 用java方式发起http请求调用网关暴露接口,要导入Spring-boot-web依赖
        String url = "https://way.jd.com/chuangxin/dxjk?"
                     +"mobile="+phone
                     +"&content=【叩丁狼】"
                     +"您的验证码是"+ code
                     +",如非本人操作，请忽略本短信"
                     +"&appkey=9b954ed90d05616a62f3aef9af81aa32";
        // 发送请求(真实发送)
        RestTemplate template = new RestTemplate();
        String forObject = template.getForObject(url, String.class);
        // 发送成功返回的forObject里面会包含Success
        if (!forObject.contains("Success")){
            throw new LogicException("短信发送失败要收费了");
        }


    }

    @Override
    public void regis(String phone, String nickname, String password, String rpassword, String verifyCode) {
        // 1.判断传入参数是否为空值
        AssertUtils.hasLength(phone,"手机号不能为空");
        AssertUtils.hasLength(nickname,"昵称不能为空");
        AssertUtils.hasLength(password,"密码不能为空");
        AssertUtils.hasLength(rpassword,"确认密码不能为空");
        AssertUtils.hasLength(verifyCode,"验证码不能为空");


        // 正则验证手机号码格式
        Pattern compile = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
        Matcher matcher = compile.matcher(phone);
        boolean matches = matcher.matches();
        if (matches == false){
            throw  new LogicException("手机号码格式错误");
        }

        // 2. 判断两次输入的密码是否一致
        AssertUtils.isEquals(password,rpassword,"两次输入密码不一致");

        // 3. 判断手机号码是否唯一
        if(!this.checkPhone(phone)){
            throw new RuntimeException("该手机号已经注册");
        }

        // 4. 判断验证码是否过期或错误
        String code =  userInfoRedisService.getVerifyCode(phone);
        if (verifyCode ==null || !code.equalsIgnoreCase(verifyCode) ){
            throw new RuntimeException("验证码失效或错误");
        }


        // 5.注册
        // 要记住没有值的属性要给个空值
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(nickname);
        userInfo.setPhone(phone);
        userInfo.setPassword(password);
        userInfo.setCity("");
        userInfo.setEmail("");
        userInfo.setCity("");
        userInfo.setHeadImgUrl("/images/BBXB.png");
        userInfo.setLevel(1);
        userInfo.setInfo("");
        userInfo.setState(UserInfo.STATE_NORMAL);
        repository.save(userInfo);


//        // 模拟注册异常
//        int i = 1 /0 ;
    }

    /**
     * 登陆验证
     * @param username
     * @param password
     * @return
     */
    @Override
    public UserInfo login(String username, String password) {
        UserInfo userInfo = repository.findByPhone(username);
        if (userInfo == null || ! userInfo.getPassword().equals(password)){
            throw new LogicException("账号或密码错误");
        }
        userInfo.setPassword("");
        return userInfo;
    }

    /**
     * 查所有
     * @return
     */
    @Override
    public List<UserInfo> listAll() {
        return repository.findAll();
    }

    @Override
    public List<UserInfo> findByCity(String name) {
        return repository.findByCity(name);
    }



//    @Override
//    public List<UserInfo> findByInAll(List<String> ids) {
//        Pageable pageable = PageRequest.of(0,9, Sort.Direction.ASC,"_id");
//        List<UserInfo> us = repository.findByIdIn(ids,pageable);
//        return us;
//    }

    @Override
    public List<UserInfo> findByIdIn(List<String> ids) {
        Pageable pageable = PageRequest.of(0,8, Sort.Direction.DESC,"_id");
        List<UserInfo> us = repository.findByIdIn(ids,pageable);
        return us;
    }

    @Override
    public List<UserInfo> findByIdAll(List<String> ids) {
        List<UserInfo> us = repository.findByIdIn(ids,null);
        return us;
    }


}
